package com.cgah

import com.cgah.Constants
import grails.converters.JSON
import com.cgah.exceptions.ListingNotFoundException

//        NOTES TO SELF
//        see http://grails.org/doc/latest/guide/6.%20The%20Web%20Layer.html for explantion of
//        how the model, view and controller work together.

class ListingController {

    static allowedMethods = [save: "POST", update: "POST", delete: "POST"]
    def springSecurityService
    def listingService
    def jmsService
    def jmsTemplate

    def index = {
        redirect(action: "list", params: params)
    }

    def list = {
        params.max = Math.min(params.max ? params.int('max') : Constants.MAX_TO_DISPLAY, 100)

        if (!params.sort) params.sort = "createdDateTime"
        if (!params.order) params.order = "desc"
        if (!params.offset) params.offset = 0;

        [listingInstanceList: listingService.list(params)];

    }

    def listingForUser = {
        // S-5: Create a view called "My Listings" that shows listings created by the logged in user
        params.max = Math.min(params.max ? params.int('max') : Constants.MAX_TO_DISPLAY, 100)

        if (!params.sort) params.sort = "createdDateTime"
        if (!params.order) params.order = "desc"
        if (!params.offset) params.offset = 0;
        [listingInstanceList: listingService.listAllForUser(params, springSecurityService.currentUser.id)];
    }

    def create = {
        return listingService.create(params);
    }

    def save = {
        def listingInstance = listingService.save(params, springSecurityService.currentUser.id)
        if (!listingInstance.hasErrors()) {
            flash.message = "${message(code: 'default.created.message', args: [message(code: 'listing.label', default: 'Listing'), listingInstance.id])}"
            redirect(action: "show", id: listingInstance.id)
        } else {
            render(view: "create", model: [listingInstance: listingInstance])
        }
    }

    def show = {
        try {
            def listingInstance = listingService.getListingById(params.id)
            Calendar now = Calendar.getInstance();
            if (listingInstance.endDateTime.before(now.time)) {
                render(view: "expired", model: [listingInstance: listingInstance])
            } else {
                [listingInstance: listingInstance]
            }
        } catch (ListingNotFoundException lnfe) {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'listing.label', default: 'Listing'), params.id])}"
            redirect(action: "list")

        }

    }


    def edit = {
        try {
            return [listingInstance: listingService.getListingById(params.id)]
        } catch (ListingNotFoundException lnfe) {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'listing.label', default: 'Listing'), params.id])}"
            redirect(action: "list")
        }
    }


    def update = {
        try {
            def listingInstance = listingService.updateListing(params)
            if (!listingInstance.hasErrors()) {
                flash.message = "${message(code: 'default.updated.message', args: [message(code: 'listing.label', default: 'Listing'), listingInstance.id])}"
                redirect(action: "show", id: listingInstance.id)
            } else {
                render(view: "edit", model: [listingInstance: listingInstance])
            }
        } catch (ListingNotFoundException lnfe) {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'listing.label', default: 'Listing'), params.id])}"
            redirect(action: "list")
        }
    }


    def delete = {
        def listingInstance = Listing.get(params.id)
        if (listingInstance) {
            try {
                listingInstance.delete(flush: true)
                flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'listing.label', default: 'Listing'), params.id])}"
                redirect(action: "list")
            }
            catch (org.springframework.dao.DataIntegrityViolationException e) {
                flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'listing.label', default: 'Listing'), params.id])}"
                redirect(action: "show", id: params.id)
            }
        }
        else {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'listing.label', default: 'Listing'), params.id])}"
            redirect(action: "list")
        }
    }


    def lastTenBids = {
        List<BidJsonResponse> bidJsonResponseList = new ArrayList();
        try {
            def lastTen = listingService.lastBids(params.id, Constants.LAST_N_BIDS)
            for (Bid b: lastTen) {
                bidJsonResponseList.add(new BidJsonResponse(b.id, b.amount, b.nextMinBid, b.dateTime, Customer.get(b.customer.id).username));
            }
        } catch (ListingNotFoundException lnfe) {
            // just eat it for now
           log.error lnfe
        }
        // even if an empty list, still render it
        render bidJsonResponseList as JSON;

    }


    // for restful services JSON support only!
    def listingDetail = {
        def listingInstance = listingService.getListingById(params.id)
        render listingInstance as JSON;
    }

    // W-2: Create a RESTful Web Service endpoint that returns a list of listings listed by a customer email address
    // (it should return a collection of links back to the endpoint created for W-1)
    def listingsForEmailAddress = {
        List<String> listingDetailLinks = new ArrayList<String>();
        Set<Listing> listings = Customer.findByEmailAddress(params.email).listings;
        for (Listing l : listings) {
            listingDetailLinks.add("/listing/" + l.id);
        }

        render listingDetailLinks as JSON;
    }

}
